<?php
/**
 * Created by PhpStorm.
 * User: stupboy
 * Date: 2018/2/6
 * Time: 16:15
 */

namespace app\api\logic;

use \think\Config;
use think\Db;
class Gps
{
    /**
     * 获取车辆GPS轨迹
     * @param int $driver_id
     * @param date $start_time
     * @param date $end_time
     * @return array
     */
    public function getTrack($driver_id = 17, $start_time = '2018-02-08 12:00:00', $end_time = '2018-02-08 12:00:00')
    {
        // $tempTrackName = md5($driver_id.$start_time.$end_time).'txt';
        $stime     = strtotime($start_time);
        $etime     = strtotime($end_time);
        $data      = [];
        $len       = ceil(($etime - $stime) / 3600);
        $len       = $len ? $len : 1;
        $mile      = 0;
        $lowSpeed  = Config::get('base.low_speed');
        $nightTime = Config::get('base.night_time');
        $night     = explode(',', $nightTime);
        $night     = count($night) == 2 ? $night : [24, 0];
        list($nightEnd, $nightStart) = $night;
        $lowTime   = 0;
        $nightKm   = 0;
        $baseTime  = 0;
        $totalTime = 0;
        $initLon   = 0;
        $initLat   = 0;
        $totalDistance = 0;
        for ($i = 0; $i <= $len; $i++) {
            $fileName = Config::get('base.gps_save_dir') . md5($driver_id) . '/' . date('YmdH', $stime + $i * 3600) . '.txt';
            if (file_exists($fileName)) {
                $file = file_get_contents($fileName);
                $records = explode("\r\n", trim($file));
                foreach ($records as $record) {
                    $row = explode("|", $record);
                    if ($row[4] >= $stime * 1000 && $row[4] <= $etime * 1000) {
                        $rows['driver_id'] = $row[0];
                        $rows['longitude'] = $row[1];
                        $rows['latitude'] = $row[2];
                        $rows['speed'] = $row[3];
                        $rows['time'] = $row[4];
                        $rows['accuracy'] = $row[5];
                        $rows['altitude'] = $row[6];
                        $rows['bearing'] = $row[7];
                        $rows['city'] = $row[8];
                        $rows['provider'] = $row[9];
                        $rows['mile'] = $row[10];
                        $distance = 0;
                        if ($initLat == 0) {
                            $initLon = $row[1];
                            $initLat = $row[2];
                        } else {
                            $distance = $this->getDistance($initLon, $initLat, $row[1], $row[2]);
                            $totalDistance = $totalDistance + $distance;
                            $initLon = $row[1];
                            $initLat = $row[2];
                        }
                        $rows['distance'] = $distance;
                        if ($baseTime == 0) {
                            $baseTime = $row[4];
                        } else {
                            $totalTime = $totalTime + ($row[4] - $baseTime);
                            if ($row[3] <= $lowSpeed) {
                                $lowTime = $lowTime + ($row[4] - $baseTime);
                            }
                            $baseTime = $row[4];
                        }
                        $mile = $mile + $row[10];
                        $hour = date('H', round($row[4] / 1000));
                        $nightKm = $hour >= $nightEnd || $hour <= $nightStart ? $nightKm + $distance : $nightKm;
                        array_push($data, $rows);
                    }
                }
            }
        }
        $lowTime = 0;// 低速行驶时间忽略
        //$finalDistance = $this->getGaoDeDistiance($data) ? : $totalDistance;
        list($data, $finalDistance,$lowTime) = $this->fixGps($data);
        // 写入文件
        // $backData        = [$finalDistance, $lowTime, $nightKm, $data];
        // $myfile          = fopen($tempTrackName, "w");
        // $txt             = json_encode($backData);
        // fwrite($myfile, $txt);
        return [$finalDistance, $lowTime, $nightKm, $data];
    }

    /**
     * 高德路径规划
     * @param $newData
     * @return int
     */
    public function getGaoDeDistiance($newData)
    {
        $key = '07e365ae157529cdb4c53be4a31f75c5';
        $url = "http://restapi.amap.com/v3/direction/driving?origin= %s &destination= %s &waypoints= %s &extensions=base&output=JSON&key=" . $key;
        $count = count($newData) - 1;
        $origin = $newData[0]['longitude'] . ',' . $newData[0]['latitude'];
        $des = $newData[$count]['longitude'] . ',' . $newData[$count]['latitude'];
        $wayArr = [];
        $baseCount = round($count / 16);
        for ($i = $baseCount; $i < $count; $i = $i + $baseCount) {
            $wayArr[] = $newData[$i]['longitude'] . ',' . $newData[$i]['latitude'];
        }
        $way = implode('|', $wayArr);
        $url = sprintf($url, $origin, $des, $way);
        $url = str_replace(' ', '', $url);
        $content = file_get_contents($url);
        $lic = json_decode($content, true);
        $juli = $lic['route']['paths'][0]['distance'] ?: 0;
        return $juli;
    }

    /**
     * 获取两点间里程 高德坐标
     * @param $lng1
     * @param $lat1
     * @param $lng2
     * @param $lat2
     * @return float|int
     */
    public function getDistance($lng1, $lat1, $lng2, $lat2)
    {
        $radLat1 = deg2rad($lat1);
        $radLat2 = deg2rad($lat2);
        $radLng1 = deg2rad($lng1);
        $radLng2 = deg2rad($lng2);
        $a = $radLat1 - $radLat2;
        $b = $radLng1 - $radLng2;
        $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000;
        return $s;
    }

    /**
     * 轨迹修复
     * @param $track
     * @param int $MaxSpeed
     * @return array
     */
    public function fixGps($track, $MaxSpeed = 180)
    {
        $a0 = []; $a1 = [];$a2 = [];$d0 = 0;
        $d1 = 0;  $d2 = 0; $lowTime = 0;
        $baseLowSpeed = Config::get('base.low_speed') ? : 0;
        foreach ($track as $key => $value) {
            if ($key == 0) {
                $a0[] = $value;
                continue;
            }
            if ($value['provider'] == 'L') {
                continue;//过滤费GPS信号
            }
            $baseTime = 0;
            $has      = -1;
            if ($a0[count($a0) - 1]) {
                $a0Value   = $a0[count($a0) - 1];
                $distance0 = $this->getDistance($value['longitude'], $value['latitude'], $a0Value['longitude'], $a0Value['latitude']);
                $time0  = ($value['time'] - $a0Value['time']) / 1000;
                if ($distance0>500) {
                    // $distance0    = $this->getOverTimeDistance($value,$a0Value);//两点直线距离超过500米则通过高德获取驾车里程
                }
                $speed0 = $distance0 / $time0 * 3.6;
                if ($speed0 < $MaxSpeed) {
                    $has = 0;
                    $baseTime = $time0;
                }
            }
            if ($a1[count($a1) - 1]) {
                $a1Value = $a1[count($a1) - 1];
                $distance1 = $this->getDistance($value['longitude'], $value['latitude'], $a1Value['longitude'], $a1Value['latitude']);
                $time1 = ($value['time'] - $a1Value['time']) / 1000;
                if ($distance1>500) {
                    // $distance1    = $this->getOverTimeDistance($value,$a1Value);
                }
                $speed1 = $distance1 / $time1 * 3.6;
                if ($speed1 < $MaxSpeed && $has == -1) {
                    $has = 1;
                    $baseTime = $time1;
                }
                if ($speed1 < $MaxSpeed && $has > -1) {
                    if ($baseTime > $time1) {
                        $has = 1;
                        $baseTime = $time1;
                    }
                }
            }

            if ($a2[count($a2) - 1]) {
                $a2Value = $a2[count($a2) - 1];
                $distance2 = $this->getDistance($value['longitude'], $value['latitude'], $a2Value['longitude'], $a2Value['latitude']);
                $time2 = ($value['time'] - $a2Value['time']) / 1000;
                if ($distance2>500) {
                    // $distance2    = $this->getOverTimeDistance($value,$a2Value);
                }
                $speed2 = $distance2 / $time2 * 3.6;
                if ($speed2 < $MaxSpeed && $has == -1) {
                    $has = 2;
                    $baseTime = $time2;
                }
                if ($speed2 < $MaxSpeed && $has > -1) {
                    if ($baseTime > $time2) {
                        $has = 2;
                        $baseTime = $time2;
                    }
                }
            }

            if ($has > -1) {
                $name   = 'a' . $has;
                $dname  = 'd' . $has;
                $ddname = 'distance' . $has;
                $speed        = ($$ddname/$baseTime)*3.6;

                $speed < $baseLowSpeed && $lowTime += $baseTime;
                $$dname += $$ddname;
                // $value['xu']   = count($$name);//调试用
                $value['addr'] = $value['longitude'] . ',' . $value['latitude'];//经纬度组合
                array_push($$name, $value);
            }

            if ($has == -1 && empty($a0)) {
                $d0 = 0;
                $a1[] = $value;
                continue;
            }
            if ($has == -1 && empty($a1)) {
                $d1 = 0;
                $a1[] = $value;
                continue;
            }
            if ($has == -1 && empty($a2)) {
                $d2 = 0;
                $a2[] = $value;
                continue;
            }
            // TODO前4个点离散情况
            if ($has > 0) {
                $a0Count = count($a0);
                $a1Count = count($a1);
                $a2Count = count($a2);
                if ($a0Count >= 10 * $a1Count) {
                    unset($a1);
                }
                if ($a0Count >= 10 * $a2Count) {
                    unset($a2);
                }

                if ($a1Count >= 10 * $a2Count) {
                    unset($a2);
                }
                if ($a1Count >= 10 * $a0Count) {
                    unset($a0);
                }

                if ($a2Count >= 10 * $a1Count) {
                    unset($a1);
                }
                if ($a2Count >= 10 * $a0Count) {
                    unset($a0);
                }
            }
        }
        $arr = count($a0)  > count($a1) ? $a0 : $a1;
        $arr = count($arr) > count($a2) ? $arr : $a2;
        $d   = max($d0, $d1, $d2);
        return [$arr, $d,$lowTime];
    }

    /**
     * 高德两点间驾车距离
     * @param $value
     * @param $a0Value
     * @param $type
     * @return mixed
     */
    public function getOverTimeDistance($value, $a0Value,$type=0)
    {
        if (empty($a0Value)) {
            return 0;
        }
        $key = '07e365ae157529cdb4c53be4a31f75c5';
        //$url     = 'http://restapi.amap.com/v3/distance?key='.$key.'&origins= %s &destination= %s &type=1';
        $url = "http://restapi.amap.com/v3/direction/driving?origin= %s &destination= %s &extensions=base&output=JSON&key=" . $key;
        $des = $value['longitude'] . ',' . $value['latitude'];
        $ori = $a0Value['longitude'] . ',' . $a0Value['latitude'];
        $url = sprintf($url, $ori, $des);
        $url = str_replace(' ', '', $url);
        $content = file_get_contents($url);
        $lic = json_decode($content, true);
        if($type ==0) return $lic['route']['paths'][0]['distance'] ?: 0;
        if($type ==1) return $lic['route']['paths'][0]['duration'] ?: 0;
        if($type ==2){
            $meter= $lic['route']['paths'][0]['distance'] ?: 0;
            $time = $lic['route']['paths'][0]['duration'] ?: 0;
            return [$time,$meter];
        }
        return $lic;
    }

    /**
     * 订单轨迹画线
     * @param $oid
     */
    public function drawOrderLine($oid,$type=0){
        if($type==0){
            $gps = Db::name('order_gps')->where('order_id',$oid)->find();
        }else{
            $gps = $oid;
            $oid = $oid['order_id'];
        }
        $a1  = $gps['from_lon'].','.$gps['from_lat'];
        $a2  = $gps['to_lon'].','.$gps['to_lat'];
        $url = 'http://restapi.amap.com/v3/direction/driving?key=07e365ae157529cdb4c53be4a31f75c5&origin=';
        $url.= $a1.'&destination='.$a2.'&originid=&destinationid=&extensions=base&strategy=0';
        $data = file_get_contents($url);
        $o    = json_decode($data);
        $arr  = [];
        $i    = 0;
        $minX = 200;
        $minY = 200;
        foreach($o->route->paths[0]->steps as $v){
            $str = $v->polyline;
            $a = explode(';',$str);
            foreach ($a as $v2){
                $xy = explode(',',$v2);
                $temp['i'] = $i;
                $minX = $minX>$xy[0] ? $xy[0] : $minX;
                $minY = $minY>$xy[1] ? $xy[1] : $minY;
                $temp['x'] = $xy[0];
                $temp['y'] = $xy[1];
                $arr[] = $temp;
                $i++;
            }
        }
        $im  = imagecreatetruecolor(2000,2000);
        $red = imagecolorallocate($im,255,255,255);//创建一个颜色，以供使用
        foreach ($arr as $k=>$v){
            if($k==0) continue;
            $x1 = round(($arr[$k-1]['x']-$minX)*10000);
            $x2 = round(($arr[$k]['x']-$minX)*10000);
            $y1 = round(($arr[$k-1]['y']-$minY)*10000);
            $y2 = round(($arr[$k]['y']-$minY)*10000);
            imageline($im,$x1,$y1,$x2,$y2,$red);
        }
        // header("content-type: image/png");
        $name = 'order/'.$oid.'.png';
        imagepng($im,$name);//输出到页面。如果有第二个参数[,$filename],则表示保存图像
        $txt     = 'order/'.$oid.'.txt';
        $myFile  = fopen($txt, "w") or die("Unable to open file!");
        $content = $minX.'-'.$minY;
        fwrite($myFile, $content);
    }

    /**
     * 轨迹图找点
     * @param $oid
     * @param $x
     * @param $y
     * @return int
     */
    public function findColor($oid,$x,$y,$r=4){
        $pic    = 'order/'.$oid.'.png';
        $txt    = 'order/'.$oid.'.txt';
        $myFile = fopen($txt, "r") or die("Unable to open file!");
        $str    = fread($myFile,filesize($txt));
        $arr    = explode('-',$str);
        $x      = round(($x - $arr[0])*10000);
        $y      = round(($y - $arr[1])*10000);
        if($x+$r<0) return 0;
        if($x+$r<0) return 0;
        $im     = ImageCreateFromPng($pic);
        $ret    = 0;
        for($i=$x-$r;$i<$x+$r;$i++){
            for($j=$y-$r;$j<$y+$r;$j++){
                $rgb = ImageColorAt($im, $i, $j);
                $c   = ($rgb >> 16) & 0xFF;
                if($c>0){
                    $ret = 1;
                    break;
                }
            }
        }
        return $ret;
    }
}